package com.cdk8s.tkey.server.util;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * MD5 加密
 * @author Cui Ying
 */
public class Md5Util {

    /**
     * md5 加盐 多次hash
     * @param salt 盐
     * @param source 待加密源数据
     * @param hashIterations hash次数
     * @return 加密后的 byte[]
     */
    public static byte[] md5(String salt, String source, int hashIterations) {
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            messageDigest.reset();
            //先加盐
            if (salt == null) {
                salt = "";
            }
            messageDigest.update(salt.getBytes(StandardCharsets.UTF_8));
            //再放需要被加密的数据
            byte[] byteArray = messageDigest.digest(source.getBytes(StandardCharsets.UTF_8));

            if (hashIterations < 1) {
                hashIterations = 1;
            }
            for (int i = 0; i < hashIterations - 1; i++) {
                messageDigest.reset();
                byteArray = messageDigest.digest(byteArray);
            }

            return byteArray;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * md5 加盐 多次hash，并转为 16进制大写字符串
     * @param salt 盐
     * @param source 待加密源数据
     * @param hashIterations hash次数
     * @return 加密后的字符串
     */
    public static String md5AndHex(String salt, String source, int hashIterations) {
        byte[] md5 = md5(salt, source, hashIterations);
        return toHexUpperString(md5);
    }

    /**
     * 转成 16 进制大写字符串
     * @param byteArray byte 数组
     * @return 字符串
     */
    public static String toHexUpperString(byte[] byteArray) {
        if (byteArray == null) {
            return null;
        }

        /* to hex str */
        StringBuilder md5StrBuff = new StringBuilder();

        for (byte b : byteArray) {
            // 转16进制，并将结果全部转为大写
            String hexString = Integer.toHexString(0xFF & b).toUpperCase();
            if (hexString.length() == 1) {
                md5StrBuff.append("0");
            }
            md5StrBuff.append(hexString);
        }

        return md5StrBuff.toString();
    }

    public static String md5AndHex(String source) {
        return md5AndHex(null, source, 1);
    }
}
